SPDX-FileCopyrightText: 2026 Ayman Amara Hammou SPDX-FileCopyrightText: 2026 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
import math
import os
import random
import bmesh
import bpycreat rad to degree
def rtd(deg):
return math.radians(deg)
os.system("cls")def clean():
bpy.ops.object.select_all(action="SELECT")
bpy.data.objects["0LIMIT"].select_set(False)
bpy.data.objects["0LIMBOOL"].select_set(False)
bpy.ops.object.delete()
bpy.ops.outliner.orphans_purge()
clean()fonction de la trame TR909
def TR909(_Name, _Pos, _Size):
bpy.ops.mesh.primitive_cube_add(location=_Pos, scale=_Size)
bpy.context.object.name = _Name
bpy.context.object.data.name = _Name + "_Mesh"
TR_Pos = [2, 4, 6, 8]
TR_created = []Barres paralleles à l’axe X
for y in TR_Pos:
for z in TR_Pos:
TR = TR909("TR X " + str(y), (5.0, y, z), (9.00 / 2, 0.15, 0.15))
TR_created.append(TR)Barres paralleles à l’axe Y
for x in TR_Pos:
for z in TR_Pos:
TR = TR909("TR Y " + str(x), (x, 5.0, z), (0.15, 9.00 / 2, 0.15))
TR_created.append(TR)Barres paralleles à l’axe Z
for x in TR_Pos:
for y in TR_Pos:
TR = TR909("TR Z " + str(x), (x, y, 5.0), (0.15, 0.15, 9.00 / 2))
TR_created.append(TR)fonction des cubes BASS
def BASS(_Name, _Pos, _Size, _Rot):
bpy.ops.mesh.primitive_cube_add(location=_Pos, scale=_Size, rotation=_Rot, size=1)
bpy.context.object.name = _Name
bpy.context.object.data.name = _Name + "_Mesh"alignement de la surface inferieur des cubes à Z=0
bpy.ops.object.origin_set(type="ORIGIN_GEOMETRY", center="BOUNDS")
bpy.context.object.location.z += _Size[2] / 2dimensionement des cubes Bass, et de la vague
dim_X = 0.6
dim_Y = 0.6
WaveNum = random.choice([-3, -2, -1, 1, 2, 3])
WaveStr = random.uniform(0.75, 2.5)double loop pour la creation des boite dans une zone carré
for x in range(17):
for y in range(17):
shake_Z = random.uniform(-0.5, 0.5) # effet de tremblementcreation de l’effet damier, permet de generer 1cube sur 2
if (x + y) % 2 == 1:
continuecreation de l’effet vague pour la hauteur des damier
normalized_y = y / 16
angle = normalized_y * math.pi * WaveNum
dim_Z = 2 + math.sin(angle) * WaveStrgeneration des cubes Bass
BASS(
"Bass " + str(x),
(0.6 + x * (dim_X - 0.05), 0.6 + y * (dim_Y - 0.05), 0),
(dim_X, dim_Y, dim_Z + shake_Z),
(0, 0, 0),
)fonction des cylindres BRUMS
def DRUMS(_Name, _Pos, _Radius, _Height):
bpy.ops.mesh.primitive_cylinder_add(location=_Pos, radius=_Radius, depth=_Height)
bpy.context.object.name = _Name
bpy.context.object.data.name = _Name + "_Mesh"alignement de la surface superieur des cylindres à Z=10
bpy.ops.object.origin_set(type="ORIGIN_GEOMETRY", center="BOUNDS")
bpy.context.object.location.z = 10 - (_Height / 2)dimensionement des cylindres Brums, et de la vague
dim_X = 0.6
dim_Y = 0.6
WaveNum = random.choice([-3, -2, -1, 1, 2, 3])
WaveStr = random.uniform(0.75, 2.5)double loop pour la creation des cylindres dans une zone carré
for x in range(17):
for y in range(17):
shake_Z = random.uniform(-0.5, 0.5) # effet de tremblement
radius = random.uniform(0.3, 0.45)creation de l’effet damier, permet de generer 1 ccylindre sur 2
if (x + y) % 2 == 1:
continuelocalisation des cylindres Brums
pos_x = 0.6 + x * (dim_X - 0.05)
pos_y = 0.6 + y * (dim_Y - 0.05)creation de l’effet vague pour la hauteur du damier
normalized_y = y / 16.0
angle = normalized_y * math.pi * WaveNum
height = 2 + math.sin(angle) * WaveStrgeneration des cylindres Brums
DRUMS("Brums " + str(x), (pos_x, pos_y, 0), radius, (height + shake_Z))fonction des grilles GUITAR
def GRID(_Name, _GridZ):
bpy.ops.mesh.primitive_grid_add(
x_subdivisions=10,
y_subdivisions=10,
location=(5, 5, _GridZ),
size=11,
)
grid = bpy.context.object
grid.name = _Name
grid.data.name = _Name + "_Mesh"dimensionement de la vague sin
WaveNum = random.choice([-3, -2, -1, 1, 2, 3])
WaveStr = random.uniform(0.75, 2.5)fonction de la vague SIN
def GRID_SIN(_Name):
for vert in bpy.data.objects[_Name].data.vertices:
normalized_x = (vert.co.x) / 11Calcul de SIN
angle = normalized_x * math.pi * WaveNum
z_offset = math.sin(angle) * WaveStr
vert.co.z = z_offsetMise à jour du mesh
bpy.data.objects[_Name].data.update()fonction des modifications
def GRID_MODIFY(_Name, _Thickness):adoucicement de la vague
waves = bpy.data.objects[_Name].modifiers.new(name="waves", type="SUBSURF")
waves.levels = 4
waves.boundary_smooth = "PRESERVE_CORNERS"bpy.ops.object.modifier_apply(modifier=”waves”)
creation de l’epaisseur
extrud = bpy.data.objects[_Name].modifiers.new(name="extrud", type="SOLIDIFY")
extrud.thickness = _Thicknessbpy.ops.object.modifier_apply(modifier=”extrud”)
Definition de les listes
total_faces = range(100)
faces_to_change = random.sample(total_faces, random.randint(0, 50))
opposite_faces = [i for i in total_faces if i not in faces_to_change]fonction de suppretion des faces
def GRID_DELETE(_Name, _Faces):
myObj = bpy.data.objects[_Name]
myObjGeom = myObj.data
myBmesh = bmesh.new()
myBmesh.from_mesh(myObjGeom)
myBmesh.faces.ensure_lookup_table()
_Faces = [myBmesh.faces[i] for i in _Faces]
bmesh.ops.delete(myBmesh, geom=_Faces, context="FACES")
myBmesh.faces.ensure_lookup_table()
isolated_faces = []
for f in myBmesh.faces:
has_neighbor = False
for e in f.edges:
if len(e.link_faces) > 1:
has_neighbor = True
break
if not has_neighbor:
isolated_faces.append(f)
bmesh.ops.delete(myBmesh, geom=isolated_faces, context="FACES")
myBmesh.to_mesh(myObjGeom)
myObj.data.update()
myBmesh.free()generation de la grille Guitar1
GRID("Guitar 1", 3)
GRID_SIN("Guitar 1")
GRID_MODIFY("Guitar 1", 0.15)
GRID_DELETE("Guitar 1", faces_to_change)generation de la grille Guitar2
GRID("Guitar 2", 7)
GRID_SIN("Guitar 2")
GRID_MODIFY("Guitar 2", 0.15)
GRID_DELETE("Guitar 2", opposite_faces)def B_Lim(_Operand_A, _Operand_B):
bool_lim = _Operand_A.modifiers.new(name="limit", type="BOOLEAN")
bool_lim.operation = "INTERSECT"
bool_lim.object = _Operand_B
bool_lim.solver = "FLOAT"
grid1 = bpy.data.objects["Guitar 1"]
grid2 = bpy.data.objects["Guitar 2"]
lim = bpy.data.objects["0LIMBOOL"]
B_Lim(grid1, lim)
B_Lim(grid2, lim)fonction des spheres HI-HATS
def HIHATS(_Name, _Pos, _Radius):
bpy.ops.mesh.primitive_uv_sphere_add(location=_Pos, radius=_Radius)
bpy.context.object.name = _Name
bpy.context.object.data.name = _Name + "_Mesh"nombre de spheres
HHnum = random.choice([0, 0, 3, 6, 9])loop de generation des spheres
for h in range(HHnum):dimensionement des spheres
_HiDim = random.uniform(0.5, 1.5)localisation des spheres
loc_x = random.uniform(1, 9)
loc_y = random.uniform(1, 9)
loc_z = random.uniform(1.5, 8.5)generation des spheres HI-HATS
HIHATS("Hi-Hats " + str(h), (loc_x, loc_y, loc_z), _HiDim)bpy.ops.object.select_all(action="DESELECT")